package com.link510.aitools.framework.view.audio;


import android.content.Context;
import android.media.AudioFormat;
import android.media.MediaRecorder;
import android.os.Handler;
import android.os.Message;
import android.view.View;

import com.link510.aitools.framework.view.audio.view.IAudioActionListen;
import com.link510.aitools.framework.view.audio.widget.RecordVoicePopWindow;
import com.orhanobut.logger.Logger;

import java.io.File;

import lombok.AllArgsConstructor;
import lombok.Getter;
import omrecorder.AudioRecordConfig;
import omrecorder.OmRecorder;
import omrecorder.PullTransport;
import omrecorder.PullableSource;
import omrecorder.Recorder;

public abstract class AudioRecordManager implements Handler.Callback, IAudioActionListen.View {


    private Context mContext = null;
    private Handler mHandler = null;

    private Recorder recorder = null;

    private IAudioState mCurAudioState;

    private RecordVoicePopWindow mRecordVoicePopWindow;//提示

    private Integer RECORD_INTERVAL = 20;

    private String SAVE_PATH = "";

    @Getter
    private File audioFile = null;

    private AudioRecordManager() {
    }

    /**
     * 监听
     *
     * @return
     */
    public abstract PullTransport.OnAudioChunkPulledListener audioChunkPulledListener();

    public abstract View getAnchor();

    /**
     * 初始化录音
     *
     * @param context 上下文
     */
    public AudioRecordManager(Context context) {
        this.mContext = context;
        this.SAVE_PATH = mContext.getCacheDir().getAbsolutePath();
        this.mHandler = new Handler(this);
    }

    private PullableSource mic() {
        return new PullableSource.Default(
                new AudioRecordConfig.Default(
                        MediaRecorder.AudioSource.MIC,
                        AudioFormat.ENCODING_PCM_16BIT,
                        AudioFormat.CHANNEL_IN_STEREO,
                        44100
                )
        );
    }

    private File file() {
        this.audioFile = new File(SAVE_PATH, System.currentTimeMillis() + "temp.wav");
        return this.audioFile;
    }

    /**
     * 开始录音
     *
     * @return 返回状态
     */
    public boolean startRecording() {

        try {

            showNormalTipView();
            showRecordingTipView();
            recorder = OmRecorder.wav(
                    new PullTransport.Default(mic(), audioChunkPulledListener()), file());

            Message e1 = Message.obtain();
            e1.what = AudioWhat.Timing.what;
            e1.obj = 10;
            this.mHandler.sendMessageDelayed(e1, (long) (this.RECORD_INTERVAL * 1000 - 10000));
            recorder.startRecording();
            return true;

        } catch (Exception ex) {
            Logger.e("开始录音");
        }

        return false;
    }


    /**
     * 停止录音
     *
     * @return 返回状态
     */
    public boolean stopRecording() {

        try {

            if (recorder == null) {
                return false;
            }

            this.mHandler.removeMessages(AudioWhat.Stop.what);
            this.mHandler.removeMessages(AudioWhat.Timing.what);
            hideTipView();
            recorder.stopRecording();
            toUploadAction(this.getAudioFile());
            return true;

        } catch (Exception ex) {
            Logger.e("停止录音");
        }

        return false;
    }

//    /**
//     * 暂停录制
//     *
//     * @return 返回状态
//     */
//    public boolean pauseRecording() {
//
//        try {
//
//            if (recorder == null) {
//                return false;
//            }
//
//            mRecordVoicePopWindow.showCancelTipView();
//            recorder.pauseRecording();
//            return true;
//
//        } catch (Exception ex) {
//            Logger.e("暂停录制");
//        }
//
//        return false;
//    }

//    /**
//     * 暂停录制
//     *
//     * @return 返回状态
//     */
//    public boolean resumeRecording() {
//
//        try {
//
//            if (recorder == null) {
//                return false;
//            }
//
//            showNormalTipView();
//            recorder.resumeRecording();
//            return true;
//
//        } catch (Exception ex) {
//            Logger.e("暂停录制");
//        }
//
//        return false;
//    }


//    /**
//     * 删除音频文件
//     *
//     * @param file 文件
//     */
//    private void deleteAudioFile(File file) {
//
//        if (file == null) {
//            return;
//        }
//
//        if (file.exists()) {
//            file.delete();
//        }
//    }


    public final boolean handleMessage(Message msg) {

        Logger.i("handleMessage " + msg.what);

        if (msg.what == AudioWhat.Stop.what) {

            stopRecording();

        } else if (msg.what == AudioWhat.Timing.what) {
            int time = (int) msg.obj;
            if (time >= 1) {
                mRecordVoicePopWindow.showTimeOutTipView(time);
                Message e1 = new Message();
                e1.what = AudioWhat.Timing.what;
                e1.obj = --time;
                this.mHandler.sendMessageDelayed(e1, 1000);
            } else {
                stopRecording();
            }
        }

        return false;
    }

    @Override
    public void showNormalTipView() {
        if (mRecordVoicePopWindow == null) {
            mRecordVoicePopWindow = new RecordVoicePopWindow(mContext);
        }

        mRecordVoicePopWindow.showAsDropDown(getAnchor());
    }

    @Override
    public void showTimeOutTipView(int remainder) {
        if (mRecordVoicePopWindow != null) {
            mRecordVoicePopWindow.showTimeOutTipView(remainder);
        }
    }

    @Override
    public void showRecordingTipView() {
        if (mRecordVoicePopWindow != null) {
            mRecordVoicePopWindow.showRecordingTipView();
        }
    }

    @Override
    public void showRecordTooShortTipView() {
        if (mRecordVoicePopWindow != null) {
            mRecordVoicePopWindow.showRecordTooShortTipView();
        }
    }

    @Override
    public void showCancelTipView() {
        if (mRecordVoicePopWindow != null) {
            mRecordVoicePopWindow.showCancelTipView();
        }
    }

    @Override
    public void hideTipView() {
        if (mRecordVoicePopWindow != null) {
            mRecordVoicePopWindow.dismiss();
        }
    }

    @Override
    public void updateCurrentVolume(double db) {
        if (mRecordVoicePopWindow != null) {
            mRecordVoicePopWindow.updateCurrentVolume(db);
        }
    }

    @AllArgsConstructor
    enum AudioWhat {

        Timing(10),
        Stop(20);

        @Getter
        final int what;

    }

}
